Editor.Property = function () {
  var resource;
  var uuidIni;
  var uuidEnd;
  var figIni;
  var figEnd;
  var figArrowPoint;
  var impl;
  
  return {
    init: function (u, ui, ue) {
      resource = new Editor.Resource();
      resource.init(u,this);
      uuidIni = ui;
      uuidEnd = ue;
      //alert("ini "+Editor.STATE.SHAPES.get(uuidIni)+" "+uuidIni);
      Editor.STATE.SHAPES.get(uuidIni).addInProperties(u);
      Editor.STATE.SHAPES.get(uuidEnd).addInProperties(u);
      impl = this;
    },
    getTypeClass: function () {
      return "property";
    },
    getInfo: function () {
      var str = '';
      if (Editor.CONFIG.DEBUG) {
        str = 'Property:\n';
        str += 'uuidIni: ' + uuidIni + '\n';
        str += 'uuidEnd: ' + uuidEnd + '\n';
        str += '\n';
      }
      //str += resource.getInfo();
      str = resource.getNamespace().getPrefix()+resource.getNamespace().getUri()
      return str;
    },
    getNamespace: function () {
      return resource.getNamespace();
    },
    setNamespace: function (n) {
      resource.setNamespace(n);
    },
    getName: function () {
      return resource.getName();
    },
    setName: function (n) {
      resource.setName(n);
    },
    getText: function () {
      var t = resource.getText();
      return t;
    },
    _remove: function () {
      resource._remove();
      this.removeLines();
    },
    remove: function () {
      var cmd = new JS.Command({
                               execute: function () {
                               resource.remove();
                               impl.removeLines();
                               },
                               undo: function () {
                                 impl.draw();
                               },
                               stack: Editor.STATE.CMDSTACK
      });
      cmd.name = 'remove property';
      cmd.execute();
    },
    draw: function () {
      resource.draw();
      this.drawLines(true);
      this.toFront();
    },
    removeLines: function () {
      figIni.remove();
      delete figIni;
      figEnd.remove();
      delete figEnd;
      figArrowPoint.remove();
      delete figArrowPoint;
    },
    drawLines: function (init) {
      var isInit = false;
      if (init) {
        isInit = true;
      } 
      var shapes = Editor.STATE.SHAPES;
      var ini = shapes.get(uuidIni);
      var end = shapes.get(uuidEnd);
      
      var px = resource.getX()+resource.getWidth()/2;
      var py = resource.getY()+resource.getHeight()/2;
      
      var ix = ini.getX()+ini.getWidth()/2;
      var iy = ini.getY()+ini.getHeight()/2;
      
      var ex = end.getX()+end.getWidth()/2;
      var ey = end.getY()+end.getHeight()/2;
      
      var pointIni = Editor.Geometry.intersectionShapeAndSegment(ini, ix, iy, px, py);
      //var pointIniR = Editor.Geometry.intersectionShapeAndSegment(resource, ix, iy, px, py);
      if (!pointIni) {pointIni = new Editor.Geometry.Vector(ix,iy)}
      //if (!pointIniR) {pointIniR = new Editor.Geometry.Vector(px,py)}
      var pointIniR = new Editor.Geometry.Vector(px,py);
      var pathIni = ["M", pointIni.x, pointIni.y, "L", pointIniR.x, pointIniR.y].join(",");
      if (isInit) {
        figIni = Editor.STATE.CANVAS.path(pathIni).attr(Editor.CONFIG.CONNECTOR_ATTR);
      } else {
        figIni.attr({path: pathIni});
      }
      
      var pointEnd = Editor.Geometry.intersectionShapeAndSegment(end, px, py, ex, ey);
      if (!pointEnd) {pointEnd = new Editor.Geometry.Vector(ex,ey)}
      //var pointEndR = Editor.Geometry.intersectionShapeAndSegment(resource, px, py, ex, ey);
      //if (!pointEndR) {pointEndR = new Editor.Geometry.Vector(px,py)}
      var pointEndR = new Editor.Geometry.Vector(px,py);
      var pathEnd = ["M", pointEndR.x, pointEndR.y, "L", pointEnd.x, pointEnd.y].join(",");
      if (isInit) {
        figEnd = Editor.STATE.CANVAS.path(pathEnd).attr(Editor.CONFIG.CONNECTOR_ATTR);
      } else {
        figEnd.attr({path: pathEnd});
      }
      
      if (isInit) {
        figArrowPoint = Editor.STATE.CANVAS.circle(pointEnd.x, pointEnd.y, Editor.CONFIG.FIGARROWPOINT_RADIUS).attr(Editor.CONFIG.FIGARROWPOINT_ATTR);
      } else {
        figArrowPoint.remove();
        figArrowPoint = Editor.STATE.CANVAS.circle(pointEnd.x, pointEnd.y, Editor.CONFIG.FIGARROWPOINT_RADIUS).attr(Editor.CONFIG.FIGARROWPOINT_ATTR);
      }
    },
    toFrontArrowPoint: function () {
      figArrowPoint.toFront();
    },
    toFront: function () {
      resource.toFront(this);
      figArrowPoint.toFront();
    },
    moveTo: function (x, y) {
      resource.moveTo(x, y);
      this.drawLines();
    },
    translate: function (dx, dy) {
      resource._translate(dx,dy);
    },
    _resize: function (dw, dh) {
      resource._resize(dw, dh);
      this.drawLines();
    },
    resize: function (dw, dh) {
      resource.resize(dw, dh);
      this.drawLines();
    },
    figure: function () {
      return Editor.STATE.CANVAS.rect(resource.getX(), resource.getY(), resource.getWidth(), resource.getHeight(), Editor.CONFIG.PROPERTY_SHAPE_ROUNDED).
      attr(Editor.CONFIG.PROPERTY_SHAPE_ATTR);
    },
    getTextAttr: function () {
      return Editor.CONFIG.PROPERTY_TEXT_ATTR;
    },
    getShapeAttr: function () {
      return Editor.CONFIG.PROPERTY_SHAPE_ATTR;
    },
    getUuid: function () {
      return resource.getUuid();
    },
    isDeleted: function () {
      return resource.isDeleted();
    },
    getX: function () {
      return resource.getX();
    },
    getY: function () {
      return resource.getY();
    },
    getWidth: function () {
      return resource.getWidth();
    },
    getHeight: function () {
      return resource.getHeight();
    },
    toString: function () {
      return 'Property-->(' + 'uuidIni: ' + uuidIni + ' , ' + 'uuidEnd: ' + uuidEnd + ' , ' + resource.toString() + ')'
    },
    select: function () {
      resource.select(this);
    },
    unselect: function () {
      resource.unselect();	
    },
    frameResize: function () {
      return resource.frameResize();
    },
    saveIni: function (e) {
      resource.saveIni(e);
    },
    getIniPosx: function () {
      return resource.getIniPosx();
    },
    getIniPosy: function () {
      return resource.getIniPosy();
    },
    mousedown: function (e) {
      if (!Editor.Util.isDragging()) {
        resource.mousedown(e);
      }
    },
    mouseover: function () {
      if (!Editor.Util.isDragging()) {
        resource.mouseover();
      }
    },
    mouseout: function () {
      if (!Editor.Util.isDragging()) {
        resource.mouseout();
      }
    },
    click: function () {
      if (!Editor.Util.isDragging()) {
        resource.click();
      }
    },
    updateText: function () {
      resource.updateText();
    },
    getMinWidth: function () {
      return resource.getMinWidth();
    },
    getMinHeight: function () {
      return resource.getMinHeight();
    },
    showEdit: function () {
      Editor.STATE.SHAPETOUPDATE = this;
      /*			$('#name').val(resource.getName());
      $('#namespacePrefix').val(resource.getNamespace().getPrefix());
      $('#namespaceUri').val(resource.getNamespace().getUri());*/
      $('#propertyName > option').removeAttr('selected');
      $('option[value='+resource.getNamespace().getUri()+']').attr('selected', 'selected');
      
      $('#dialogAddProperty').jqm({overlay: 40, modal: true}).jqmShow('fast');
    },
    getDeckEdit: function () {
      return resource.getDeckEdit();
    },
    getDraggerConnector: function () {
      return resource.getDraggerConnector();
    },
    getUuidIni: function () {
      return uuidIni;
    },
    getUuidEnd: function () {
      return uuidEnd;
    },
    onmouseup: function () {
    },
    hideLines: function () {	
      figIni.attr(Editor.CONFIG.UNVISIBLE_ATTR);
      figEnd.attr(Editor.CONFIG.UNVISIBLE_ATTR);
      figArrowPoint.attr(Editor.CONFIG.UNVISIBLE_ATTR);
    },
    showLines: function () {
      figIni.attr(Editor.CONFIG.VISIBLE_ATTR);
      figEnd.attr(Editor.CONFIG.VISIBLE_ATTR);
      figArrowPoint.attr(Editor.CONFIG.VISIBLE_ATTR);
    },
    toObject: function () {
      return {
        'type': 'property',
        'uuidIni': uuidIni,
        'uuidEnd': uuidEnd,
        'resource': resource.toObject()
      }
    },
  }
}
